﻿using System;
using System.Net.Http;
using System.Threading.Tasks;

using IdentityModel.Client;

using Newtonsoft.Json.Linq;

namespace ResourceOwnerPasswordConsoleApp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            bool verifySuccess = false;
            TokenResponse tokenResponse = null;
            while (!verifySuccess)
            {
                Console.WriteLine("请输入用户名：");
                string userName = Console.ReadLine();
                Console.WriteLine("请输入密码：");
                string password = Console.ReadLine();

                //discovery endpoint - 发现终结点
                HttpClient client = new HttpClient();
                DiscoveryDocumentResponse disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
                if (disco.IsError)
                {
                    Console.WriteLine($"[DiscoveryDocumentResponse Error]: {disco.Error}");
                    return;
                }

                //request assess token - 请求访问令牌
                tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
                {
                    Address = disco.TokenEndpoint,
                    ClientId = "client1",
                    ClientSecret = "secret",
                    Scope = "api1",
                    UserName = userName,
                    Password = password
                });
                if (tokenResponse.IsError)
                {
                    //ClientId 与 ClientSecret 错误，报错：invalid_client
                    //Scope 错误，报错：invalid_scope
                    //UserName 与 Password 错误，报错：invalid_grant
                    string errorDesc = tokenResponse.ErrorDescription;
                    if (string.IsNullOrEmpty(errorDesc)) errorDesc = "";
                    if (errorDesc.Equals("invalid_username_or_password"))
                    {
                        Console.WriteLine("用户名或密码错误，请重新输入！");
                    }
                    else
                    {
                        Console.WriteLine($"[TokenResponse Error]: {tokenResponse.Error}, [TokenResponse Error Description]: {errorDesc}");
                    }
                    Console.WriteLine("");
                    continue;
                }
                else
                {
                    Console.WriteLine("");
                    Console.WriteLine($"Access Token: {tokenResponse.AccessToken}");
                    verifySuccess = true;
                }
            }

            //call API Resource - 访问API资源
            HttpClient apiClient = new HttpClient();
            apiClient.SetBearerToken(tokenResponse?.AccessToken);
            HttpResponseMessage response = await apiClient.GetAsync("http://localhost:6000/weatherforecast");
            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine($"API Request Error, StatusCode is : {response.StatusCode}");
            }
            else
            {
                string content = await response.Content.ReadAsStringAsync();
                Console.WriteLine("");
                Console.WriteLine($"Result: {JArray.Parse(content)}");
            }

            Console.ReadKey();
        }
    }
}
